package seqAlignment.utils;

import java.io.BufferedReader;
import java.io.EOFException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class SubstitutionMatrix {

	BufferedReader reader;
	File sourceFile;
	List<List<Integer>> matrix;
	String[] xMap;
	List<String> yMap;
	
	Map<String, Integer> xStrMapping=null;
	Map<String, Integer> yStrMapping=null;
	int[][] valueMatrix=null;

	public SubstitutionMatrix() {
	}

	public void setFile(File file) throws IOException {
		sourceFile = file;
		reader = new BufferedReader(new FileReader(sourceFile));
		init();
	}

	protected void init() throws IOException {
		String line;

		matrix = new LinkedList<List<Integer>>();
		yMap = new LinkedList<String>();
		xStrMapping=null;
		yStrMapping=null;
		valueMatrix=null;
		
		line = reader.readLine();
		for(int count=0; line!=null; count++) {
			if (count == 0) {
				initXMap(line);
			} else {
				appendToMatrix(count, line);
			}
			count++;
			line = reader.readLine();
		}
		reader.close();
	}

	private void appendToMatrix(int count, String line) {
		String[] pcs = line.split("\\s+");
		yMap.add(pcs[0]);

		List<Integer> matrixLine = new ArrayList<Integer>(pcs.length - 1);
		matrix.add(matrixLine);
		for (int i = 1; i < pcs.length; i++) {
			matrixLine.add(new Integer(pcs[i]));
		}
	}

	private void initXMap(String line) {
		String[] pcs=line.split("\\s+");
		xMap=new String[pcs.length-1];
		for (int i=1;i<pcs.length; i++) {
			xMap[i-1]=pcs[i];
		}
	}

	public Map<String,Integer> getXStrMapping() {
		if (xStrMapping==null) {
			xStrMapping=new HashMap<String, Integer>(xMap.length);
			for (int i=0;i<xMap.length; i++) {
				xStrMapping.put(xMap[i], new Integer(i));
			}
		}
		return xStrMapping;
	}

	public Map<String,Integer> getYStrMapping() {
		if (yStrMapping==null) {
			yStrMapping=new HashMap<String, Integer>(yMap.size());
			for (int i=0;i<yMap.size(); i++) {
				yStrMapping.put(yMap.get(i), new Integer(i));
			}
		}
		return yStrMapping;
	}

	public int[][] getValueMatrix() {
		if (valueMatrix==null) {
			valueMatrix=new int[xMap.length][yMap.size()];
			for (int x=0;x<xMap.length;x++) {
				List<Integer> matrixLine=matrix.get(x);
				for (int y=0; y<yMap.size();y++) {
					valueMatrix[x][y]=matrixLine.get(y).intValue();
				}
			}
		}
		return valueMatrix;
	}

}
